package com.yan.qing.util;

import lombok.extern.slf4j.Slf4j;

import java.io.Serializable;
import java.lang.invoke.SerializedLambda;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.List;

/**
 * 获取类的属性，通过get/set方法
 *
 * @author ws
 * @Date 11:19 2023/2/13
 **/
@Slf4j
public class FieldConvertUtils {
    /***
     * 转换方法引用为属性名
     * @param fn xx::getName
     * @return name
     */
    public static <T> List<String> convertToFieldNames(IGetter<T>... fn) {
        List<String> names = new ArrayList<>();
        List<SerializedLambda> serializedLambdas = getSerializedLambdas(fn);
        for (SerializedLambda lambda : serializedLambdas) {
            String methodName = lambda.getImplMethodName();
            String prefix = null;
            if (methodName.startsWith("get")) {
                prefix = "get";
            } else if (methodName.startsWith("is")) {
                prefix = "is";
            }
            if (prefix == null) {
                log.warn("无效的getter方法: " + methodName);
            }
            String s = lowerFirst(methodName.replace(prefix, ""));
            names.add(s);
        }
        return names;

    }

    /**
     * 通过setter获取
     *
     * @param fn setter引用
     * @return 返回转换后的字段集合
     */
    public static <T, U> List<String> convertToFieldName(ISetter<T, U> fn) {
        List<String> names = new ArrayList<>();
        List<SerializedLambda> serializedLambdas = getSerializedLambdas(fn);
        for (SerializedLambda lambda : serializedLambdas) {
            String methodName = lambda.getImplMethodName();
            if (!methodName.startsWith("set")) {
                log.warn("无效的setter方法：" + methodName);
            }
            names.add(lowerFirst(methodName.replace("set", "")));
        }
        return names;

    }

    public static List<SerializedLambda> getSerializedLambdas(Serializable... fns) {
        List<SerializedLambda> lambdas = new ArrayList<>();
        for (Serializable fn : fns) {
            try {
                Method method = fn.getClass().getDeclaredMethod("writeReplace");
                method.setAccessible(Boolean.TRUE);
                SerializedLambda lambda = (SerializedLambda) method.invoke(fn);
                lambdas.add(lambda);
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
        return lambdas;
    }

    /**
     * 将字符串的首字母转小写
     *
     * @param str 需要转换的字符串
     * @return 首字母小写
     */
    private static String lowerFirst(String str) {
        char[] cs = str.toCharArray();
        cs[0] += 32;
        return String.valueOf(cs);
    }

}
